<?php
/**
 * @author jonathan <jo.link.noir@gmail.com>
 * @version 1.0 : jo_link_noir
 * @date 19-06-2010
 */
abstract class SW_Planet_Storage_Treatment
{
	/** @var array : {id => SW_Element, ...}*/
	protected $elements = array();

	/** @var array : {id_group => {SW_Element, ...}, ...} Référence sur des elements*/
	protected $groupElements = array();

	/** @var int */
	protected $idPlanet;

	/** @var SW_Player */
	protected $player;

	/** @var bool */
	private $isInitialized = false;

	/** @var SW_Dependency*/
	protected $dependency;


	/**
	 * @return void
	 */
	abstract protected function _init();


	/**
	 * @param SW_Player $player
	 * @param int $planet
	 * @param SW_Dependency $dependency = null
	 */
	protected function __construct(SW_Player $player, $idPlanet, SW_Dependency $dependency = null)
	{
		$this->player = $player;
		$this->idPlanet = $idPlanet;
		$this->dependency = $dependency;
	}

	/**
	 * @return void
	 */
	final public function init()
	{
		if (!$this->isInitialized)
		{
			$this->isInitialized = true;
			$this->_init();
		}
	}

	/**
	 * @return bool
	 */
	final public function isInit()
	{
		return $this->isInitialized;
	}

	/**
	 * Ajoute un élement
	 * @param SW_Element $element
	 */
	public function add(SW_Element $element)
	{
		$this->elements[$element->getId()] = $element;

		//if (!isset($this->groupElements[$element->getGroup()]))
		//	$this->groupElements[$element->getGroup()] = array();
		$this->groupElements[$element->getGroup()][$element->getId()] = $element;
	}

	/**
	 * Supprime un élément
	 * @param int $id
	 */
	protected function remove($id)
	{
		if (isset($this->elements[$id]))
		{
			$group = $this->elements[$id]->getGroup();
			unset($this->groupElements[$group][$id], $this->elements[$id]);
			if (empty($this->groupElements[$group]))
				unset($this->groupElements[$group]);
		}
	}

	/**
	 * Vérifie qu'un élément existe
	 * @param int $id
	 * @return bool
	 */
	public function exists($id)
	{
		return isset($this->elements[$id]);
	}

	/**
	 * Vérifie si un groupe d'élément existe
	 * @param int $group
	 * @return bool
	 */
	public function existsGroup($group)
	{
		return isset($this->groupElements[$group]);
	}

	/**
	 * @param int $id
	 * @return SW_Element|null
	 */
	public function get($id)
	{
		return isset($this->elements[$id]) ? $this->elements[$id] : null;
	}

	/**
	 * @param int $group
	 * @return array {id_group => SW_Element, ...}
	 */
	public function getGroup($group)
	{
		return isset($this->groupElements[$group]) ? $this->groupElements[$group] : array();
	}

	/**
	 * @return array : {id => SW_Element, ...}
	 */
	public function gets()
	{
		return $this->elements;
	}

	/**
	 * @return array : {id_group => {SW_Element, ...}, ...}
	 */
	public function getGroups()
	{
		return $this->groupElements;
	}

	/**
	 * @param array $ids : id des éléments
	 * @return array : {id_group => {id_e => SW_Element, …}, …}
	 */
	public function getElementsPerGroups(array $ids)
	{
		$ret = array();
		foreach ($ids as $id)
			if (isset($this->elements[$id]))
				$ret[$this->elements[$id]->getGroup()][$id] = $this->elements[$id];
		return $ret;
	}

	/**
	 * @return int
	 */
	public function getIdPlanet()
	{
		return $this->idPlanet;
	}

	/**
	 * Retourne une instance du type demander de la planète
	 * @param string $instance
	 * @return SW_Planet_Storage_Treatment|null
	 */
	final public function getSiblingInstance($instance)
	{
		return $this->player->offsetGet(SW_Planet::INDEX)->getInstance($instance, $this->idPlanet);
	}

	/**
	 * Retourne une instance de la planète
	 * @return SW_Planet|null
	 */
	final public function getPlanetInstance()
	{
		return $this->player->offsetGet(SW_Planet::INDEX);
	}

	/**
	 * @return SW_Player
	 */
	final public function getPlayer()
	{
		return $this->player;
	}

	/**
	 * @exception LogicException Impossible de cloner les éléments de type SW_Planet_Storage_Treatment
	 */
	final public function __clone()
	{
		throw new LogicException('Impossible de cloner les éléments de type SW_Planet_Storage_Treatment');
	}

	public function setDependency(SW_Dependency $dependency)
	{
		$this->dependency = $dependency;
	}

	/**
	 * @return 'storage'
	 */
	public function __toString()
	{
		return 'storage';
	}

	public function __destruct()
	{}
}